package com.mx.tool.commit;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: mengxiang.
 * @create: 2021-03-08 10:06
 * @Description:
 */
public class CommitMessage {

    public static final Pattern COMMIT_FIRST_LINE_FORMAT = Pattern.compile("^([a-z]+)(\\((.+)\\))?: (.+)");
    public static final Pattern COMMIT_CLOSES_FORMAT = Pattern.compile("Closes (.+)");

    private Type type;
    private String shortDescription;

    private CommitMessage() {
    }

    public CommitMessage(Type type, String shortDescription) {
        this.type = type;
        this.shortDescription = shortDescription;
    }

    @Override
    public String toString() {

        return type.label() +
                ": " +
                shortDescription;
    }

    public static CommitMessage parse(String message) {
        CommitMessage commitMessage = new CommitMessage();

        try {
            Matcher matcher = COMMIT_FIRST_LINE_FORMAT.matcher(message);
            if (!matcher.find()) return commitMessage;

            commitMessage.type = Type.valueOf(matcher.group(1).toUpperCase());
            commitMessage.shortDescription = matcher.group(4);

            String[] strings = message.split("\n");
            if (strings.length < 2) return commitMessage;

            int pos = 1;
            StringBuilder stringBuilder;

            stringBuilder = new StringBuilder();
            for (; pos < strings.length; pos++) {
                String lineString = strings[pos];
                if (lineString.startsWith("BREAKING") || lineString.startsWith("Closes") || lineString.equalsIgnoreCase("[skip ci]"))
                    break;
                stringBuilder.append(lineString).append('\n');
            }

            stringBuilder = new StringBuilder();
            for (; pos < strings.length; pos++) {
                String lineString = strings[pos];
                if (lineString.startsWith("Closes") || lineString.equalsIgnoreCase("[skip ci]")) break;
                stringBuilder.append(lineString).append('\n');
            }

            matcher = COMMIT_CLOSES_FORMAT.matcher(message);
            stringBuilder = new StringBuilder();
            while (matcher.find()) {
                stringBuilder.append(matcher.group(1)).append(',');
            }
            if (stringBuilder.length() > 0) stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return commitMessage;
    }

    public Type type() {
        return type;
    }


    public String shortDescription() {
        return shortDescription;
    }

}